<?php
/**
 * Created by Chen.
 * author: 1481746137@qq.com
 * Date: 2018/1/31
 * Time: 10:35
 */

namespace app\v2\model;


use apiocr\AipOcr;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\Model;
use think\Request;
use app\v2\model\UserInfo;


class IdcardOcr extends Model
{

    protected $name = 'invite_code';

    const APP_KEY = 'sq6dDaw66z_u4zsFzkh5vIGodPxaJWYs';
    const APP_SECRET = '2xlIU8XW2iyXgj2DjNOQVpng0DQPjBgA';
    const GET_TOKEN = 'https://api.megvii.com/faceid/lite/get_token';
    const VERIFICATION = 'https://api.megvii.com/faceid/lite/do';
    const GET_RESULT = 'https://api.megvii.com/faceid/lite/get_result';

    public function __construct($data = [])
    {
        parent::__construct($data);
        $this->notify_url = config('domainpath')['api'] . '/v2/ocrNotify';  //识别同步回调地址（成功页面）
        $this->return_url = config('domainpath')['api'] . '/v2/ocrReturn';  //识别yb地址
    }


    /**
     * 身份识别
     * @author cxr <1481746137@qq.com>
     * @param $url
     * @return array|bool
     */
    public function Identify($uid)
    {
        #生成Token 记录bizid
        $token = $this->getToken();
        if (isset($token['token'])) {
            $data['face_bizid'] = $token['biz_id'];
            $UserInfo = UserInfo::get(['uid' => $uid]);
            if (!$UserInfo->save($data)) {
                $this->error = "保存失败";
                return false;
            }
        } else {
            $this->error = $token['error_message'];
            return false;
        }

        #返回识别URL
        $url = $this->doVerification($token['token']);
        return $url;

    }

    /**
     * 获取token
     * @author cxr <1481746137@qq.com>
     * @return mixed|string
     */
    public function getToken()
    {
        $fields = [
            'api_key' => SELF::APP_KEY,
            'api_secret' => SELF::APP_SECRET,
            'return_url' => $this->return_url,
            'notify_url' => $this->notify_url,
            'biz_no' => '20180000000001',
            'comparison_type' => '1',
            'idcard_mode' => '2'
        ];
        $res = $this->curlPost(SELF::GET_TOKEN, $fields);
        return $res;
    }

    /**
     * 结果查询 用于返回身份证图片
     * @author cxr <1481746137@qq.com>
     * @return mixed|string
     */
    public function getResult($biz_id)
    {
        $fields = [
            'api_key' => SELF::APP_KEY,
            'api_secret' => SELF::APP_SECRET,
            'biz_id' => $biz_id,
            'return_image' => '4' // 返回所有图像
        ];
        $query = http_build_query($fields);
        $res = $this->curlPost(SELF::GET_RESULT.'?'.$query);
        return $res;
    }

    /**
     * 返回识别URL
     * @author cxr <1481746137@qq.com>
     * @param $token
     * @return mixed|string
     */
    public function doVerification($token)
    {
        return SELF::VERIFICATION . "?token=$token";
    }

    /**
     * 身份识别异步回调
     * @author cxr <1481746137@qq.com>
     * @param $param
     */
    public function notifyUrl($param)
    {
        $result = $param;
        $faceResult = '';

        if (isset($result['data'])) {
            $data = json_decode($result['data']);
            if ($data->status == 'OK') {
                try{

                    if($data->liveness_result['result'] == 'PASS'){
                        if((float)$data->verify_result['result_faceid']['confidence'] >= (float)$data->verify_result['result_faceid']['thresholds']['1e-3']){

                            #身份信息
                            $id_card_number = $data->idcard_info['front_side']['ocr_result']['id_card_number'];;
                            $race = $data->idcard_info['front_side']['ocr_result']['race'];
                            $sex = $data->idcard_info['front_side']['ocr_result']['gender'];
                            $name = $data->idcard_info['front_side']['ocr_result']['name'];
                            $address = $data->idcard_info['front_side']['ocr_result']['address'];

                            #反面
                            $issued_by = $data->idcard_info['back_side']['ocr_result']['issued_by'];
                            $valid_date = $data->idcard_info['back_side']['ocr_result']['valid_date'];
                            $birthday = join('-',$data->idcard_info['front_side']['ocr_result']['birthday']);

                            $faceResult = '通过'.$id_card_number.$race.$sex.$name.$address.$issued_by.$valid_date.$birthday;


                        }else{
                            $faceResult = '人脸验证失败';
                        }

                    }else{
                        $faceResult = '活体验证未通过';
                    }

                }catch(\Exception $e) {
                    @file_put_contents(LOGS_DIR_NAME . "face_log.txt", '认证时间:' . date('Y-m-d H:i:s', time()) . " 结果:出现异常,回调详情:" . $result['data'] . "\n\n", FILE_APPEND);
                    return false;
                }
            }else{
                $faceResult = '未完成流程';
            }

            @file_put_contents(LOGS_DIR_NAME . "face_log.txt", '认证时间:' . date('Y-m-d H:i:s', time()) . " 结果:$faceResult,回调详情:" . $result['data'] . "\n\n", FILE_APPEND);

        }
        return 'ok';
    }

    /**
     * 身份识别同步回调
     * @author cxr <1481746137@qq.com>
     * @param $param
     */
    public function returnUrl($param)
    {
        $result = $param;
        $faceResult = '';

//        var_dump(json_decode($result['data']) );
//        exit;

        if (isset($result['data'])) {
            $data = json_decode($result['data'],true);
            if ($data['status'] == 'OK') {

                $biz_id = $data['biz_info']['biz_id'];

                #结果反查
                $data = $this->getResult($biz_id);

                try{

                    if($data['liveness_result']['result'] == 'PASS'){
                        if((float)$data['verify_result']['result_faceid']['confidence'] >= (float)$data['verify_result']['result_faceid']['thresholds']['1e-3']){

                            #身份信息
                            $info['id_card']  = $data['idcard_info']['front_side']['ocr_result']['id_card_number'];;
                            $info['race'] = $data['idcard_info']['front_side']['ocr_result']['race'];
                            $info['sex'] = $data['idcard_info']['front_side']['ocr_result']['gender'];
                            $info['name'] = $data['idcard_info']['front_side']['ocr_result']['name'];
                            $info['idcard_address'] = $data['idcard_info']['front_side']['ocr_result']['address'];

                            #反面
                            $info['issued_by'] = $data['idcard_info']['back_side']['ocr_result']['issued_by'];
                            $info['valid_date'] = $data['idcard_info']['back_side']['ocr_result']['valid_date'];
                            $info['birthday'] = join('-',$data['idcard_info']['front_side']['ocr_result']['birthday']);

                            #取得身份证正反面 上传七牛云
                            $front_img = $data['images']['image_idcard_front'];
                            $back_img = $data['images']['image_idcard_back'];
                            $info['$id_card_img1'] = $this->uploadBase64($front_img);
                            $info['$id_card_img2'] = $this->uploadBase64($back_img);

                            #保存信息
                            UserInfo::get(['face_bizid'=>$biz_id])->save($info);

                            $faceResult = '通过'.json_encode($info,true);
                        }else{
                            $faceResult = '人脸验证失败';
                        }

                    }else{
                        $faceResult = '活体验证未通过';
                    }

                }catch(\Exception $e) {
                    @file_put_contents(LOGS_DIR_NAME . "face_log.txt", '认证时间:' . date('Y-m-d H:i:s', time()) . " 结果:出现异常,回调详情:" . $result['data'] . "\n\n", FILE_APPEND);
                    return false;
                }
            }else{
                $faceResult = '未完成流程';
            }

            @file_put_contents(LOGS_DIR_NAME . "face_log.txt", '认证时间:' . date('Y-m-d H:i:s', time()) . " 结果:$faceResult,回调详情:" . $result['data'] . "\n\n", FILE_APPEND);

        }
        return $faceResult;
    }


    public function uploadBase64($pic)
    {
        $token=$this->getQiniuToken();
        if(!$pic){
            return resultArray(['error' => "没有获取到图片信息"]);
        }
        $uploadManager=new  UploadManager();

        $type="jpg";
        $name=date("YmdHis").rand(1,1000).".".$type;
        $filePath=$pic;

        list($ret,$err)=$uploadManager->putFile($token,$name,$filePath,null,$type,false);
        if($err){//上传失败
            return resultArray(['error' => "上传失败"]);
        }else{//成功
            //添加信息到数据库
            $url = "http://upload.yueguangbaika.com/".$ret['key'];
            return $url;
        }
    }

    /**
     * 生成上传凭证
     * @return string
     */
    private function getQiniuToken(){

        $accessKey = 'VILnQPToTZGD5b3fvEw8oFkkdGnlNxvGxQQ-fq-5';
        $secretKey = 'SH3ak_rrYL6Yxq2db1UFb5ibtHF9l2hKDHmtWhdu';
        $auth=new Auth($accessKey, $secretKey);

        // 要上传的空间
        // $bucket = 'w-bjj';
        $bucket = 'qh-yueguangbaika';
        return $auth->uploadToken($bucket);//生成token
    }


    private function curlPost($url, $data = '',$GET = false)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        if (curl_errno($curl)) {
            return 'ERROR ' . curl_error($curl);
        }
        curl_close($curl);
        return json_decode($output, true);
    }

}